﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;

namespace pos
{
    public partial class saleOrderRetail : application.baseMasterDetailEntry
    {
        public saleOrderRetail()
        {
            try
            {
                InitializeComponent();
                myMasterSource = orderSource;
                myMasterEditKeyFldName = mySalesDS.Order.OrderNoColumn.ColumnName;
                myMasterKeyFldName = mySalesDS.Order.orderIdColumn.ColumnName;
                editKeyEd.MaxLength = mySalesDS.Order.OrderNoColumn.MaxLength;

                //Detail  grid
                myDetailSource = detailSource;
                detailSource.DataSource = mySalesDS.OrderDetail;
                this.myDetailGrid.Init(detailSource);
                this.myDetailGrid.myOnCellValueChanged += new common.controls.baseDataGridView.OnCellEvent(gridValueChanged);

                if (LoadConfig() == false)
                {
                    //QuitApplication();
                    this.Close();
                }
                Init();
                if ( (CommonTypes.Settings.sysLoginInfo.Roles & (int)CommonTypes.UserRoles.PosOperator) >0 && 
                     this.myPermission.Add) this.AddNewRow();
                this.isDebugMode = false;
                LockEdit();
            }
            catch (Exception er)
            {
                this.ShowError(er);
            }
        }

        public bool isAdminMode
        {
            get
            {
                return this.myMasterNavigator.Visible;
            }
            set
            {
                this.myMasterNavigator.Visible = value;
                this.custCodeEd.isRequired = (value == false);
                this.MainMenuVisible = value;
                custCodeEd.myOnFindEnable = value;
                exitBtn.Enabled = isAdminMode;
                LockEditData(this.isLockEdit);
            }
        }

        private bool isDebugMode
        {
            set
            {
                this.myDetailGrid.SetColumnReadOnly(sales.Controls.gridOrderDetail.ColumnNames.price.ToString(), !value);
                this.myDetailGrid.SetColumnReadOnly(sales.Controls.gridOrderDetail.ColumnNames.amount.ToString(), !value);
                this.myDetailGrid.DisbaleReadOnlyColumns();
            }
        }
        private bool sysCheckInventoryQty = true; //Turn on/off inventory check

        class InventoryData
        {
            public DateTime OnDate = DateTime.Today;
            public string ItemSubCode = "";
            inventory.InventoryInfo InventoryInfo = new inventory.InventoryInfo();
            public void Restart()
            {
                InventoryInfo.Restart();
            }
            public data.tmpDS.inventoryRow GetInventory(string itemCode)
            {
                DateTime inventoryDate = DataAccess.SysLibs.GetInventoryDate(this.OnDate);
                data.tmpDS.inventoryRow row = this.InventoryInfo.Find(inventoryDate, Settings.myPosConfig.HouseCode, itemCode, this.ItemSubCode);
                if (row == null)
                {
                    DataAccess.DataLibs.InventoryOptions option = new DataAccess.DataLibs.InventoryOptions();
                    option.ToDate = OnDate;
                    option.HouseCodeList = new StringCollection();
                    option.HouseCodeList.Add(Settings.myPosConfig.HouseCode);

                    option.ItemAndSubCodeList = new DataAccess.DataLibs.MyItemCodeList();
                    option.ItemAndSubCodeList.Add(new DataAccess.DataLibs.MyItemCode(itemCode, this.ItemSubCode));

                    data.tmpDS.inventoryDataTable dataTbl = new data.tmpDS.inventoryDataTable();
                    dataTbl.Clear();
                    DataAccess.DataLibs.GetSumData(dataTbl, option);
                    this.InventoryInfo.Add(dataTbl);
                }
                return this.InventoryInfo.Find(inventoryDate, Settings.myPosConfig.HouseCode, itemCode, this.ItemSubCode);
            }
            public data.tmpDS.inventoryRow UpdateInventory(string itemCode, decimal qty)
            {
                data.tmpDS.inventoryRow row = GetInventory(itemCode);
                if (row == null) return null;
                row.qty -= qty;
                row.eopQty -= qty;
                return row;
            }
            public void SaveInventoryDetail(data.salesDS.OrderRow orderRow, data.salesDS.OrderDetailDataTable detailTbl)
            {
                data.applicationDS.VoucherDataTable voucherTbl = new data.applicationDS.VoucherDataTable();
                data.applicationDS.VoucherRow voucherRow = voucherTbl.NewVoucherRow();

                //Delete old data if any
                if (orderRow.IsrefVoucherIdNull() == false)
                {
                    DataAccess.DataLibs.DeleteInventoryDetail(orderRow.refVoucherId);
                    DataAccess.DataLibs.LoadData(voucherTbl, orderRow.refVoucherId);
                    voucherRow = voucherTbl[0];
                    voucherRow.onDate = orderRow.onDate;
                    DataAccess.DataLibs.UpdateData(voucherRow);
                }
                else
                {
                    //Create new voucher
                    DataAccess.DataLibs.InitData(voucherRow);
                    voucherRow.voucherId = application.SysLibs.GetNewDataKey(voucherTbl.TableName, CommonTypes.Settings.sysDataKeyPrefix, CommonTypes.Settings.sysDataKeySize);
                    voucherRow.onDate = orderRow.onDate;
                    voucherRow.notes1 = "Xuất kho bán hàng tại POS : " + Settings.myPosConfig.HouseCode;
                    voucherRow.createById = CommonTypes.Settings.sysLoginInfo.UserId;
                    voucherRow.ownerId = Settings.myPosConfig.CompanyId;
                    voucherRow.voucherType = CommonTypes.InventoryConsts.constVoucherTypeItemOUT_POS;
                    voucherRow.voucherNo = voucherRow.voucherId;
                    voucherTbl.AddVoucherRow(voucherRow);
                    DataAccess.DataLibs.UpdateData(voucherRow);
                }

                //Update orderRow.refVoucherId to keep track of related record
                orderRow.refVoucherId = voucherRow.voucherId;
                DataAccess.DataLibs.UpdateData(orderRow);

                //Create Inventory details
                data.applicationDS.InventoryDetailDataTable inventoryDetailTbl = new data.applicationDS.InventoryDetailDataTable();
                for (int idx = 0; idx < detailTbl.Count; idx++)
                {
                    if (detailTbl[idx].RowState == DataRowState.Deleted) continue;

                    data.applicationDS.InventoryDetailRow inventoryRow = inventoryDetailTbl.NewInventoryDetailRow();
                    DataAccess.DataLibs.InitData(inventoryRow);
                    inventoryRow.voucherId = orderRow.refVoucherId;
                    inventoryRow.houseCode = Settings.myPosConfig.HouseCode;
                    inventoryRow.itemCode = detailTbl[idx].itemCode;
                    inventoryRow.qty = detailTbl[idx].qty;
                    inventoryRow.isOut = true;
                    inventoryDetailTbl.AddInventoryDetailRow(inventoryRow);
                }
                DataAccess.DataLibs.UpdateData(inventoryDetailTbl);
            }
            public void Refresh(sales.Controls.gridOrderDetail grid)
            {
                string itemCode;
                data.tmpDS.inventoryRow inventoryRow;
                for (int idx = 0; idx < grid.RowCount; idx++)
                {
                    if (grid.Rows[idx].Cells[inventory.Controls.gridInventoryDetail.ColumnNames.itemCode.ToString()].Value == null) continue;
                    itemCode = grid.Rows[idx].Cells[inventory.Controls.gridInventoryDetail.ColumnNames.itemCode.ToString()].Value.ToString().Trim();
                    if (common.StringLibs.IsNullOrEmpty(itemCode)) continue;
                    inventoryRow = GetInventory(itemCode);
                    if (inventoryRow!=null)
                         grid.Rows[idx].Cells[inventory.Controls.gridInventoryDetail.ColumnNames.whQty.ToString()].Value = inventoryRow.eopQty;
                    else grid.Rows[idx].Cells[inventory.Controls.gridInventoryDetail.ColumnNames.whQty.ToString()].Value = 0;
                }
            }
        }
        InventoryData myInventoryData = new InventoryData();
        private string myCurrency = CommonTypes.Settings.sysMainCurrency;

        #region override
        protected override string GetMasterEditKeyId(DataRow dr)
        {
            return dr[mySalesDS.Order.orderIdColumn.ColumnName].ToString();
        } 
        protected override void ArrangeGrid()
        {
            base.ArrangeGrid();
            this.myDetailGrid.AutoArrange();
        }
        public override void LockEdit()
        {
            base.LockEdit();
            if (finishBtn!=null) finishBtn.Enabled = this.myPermission.Add;
            if (dateEd != null) dateEd.Enabled = false;
        }
        protected override common.controls.baseDataGridView CreateDetailGrid()
        {
            sales.Controls.gridOrderDetail grid = new sales.Controls.gridOrderDetail();
            this.gridSplitContainer.Panel1.Controls.Add(grid);
            grid.Dock = DockStyle.Fill;
            return grid;
        }
        protected override void SetDetailGrid()
        {
            base.SetDetailGrid();
            string[] colList = new string[]{sales.Controls.gridOrderDetail.ColumnNames.itemCode.ToString(), 
                                            sales.Controls.gridOrderDetail.ColumnNames.itemName.ToString(), 
                                            sales.Controls.gridOrderDetail.ColumnNames.whQty.ToString(),
                                            sales.Controls.gridOrderDetail.ColumnNames.qty.ToString(),
                                            sales.Controls.gridOrderDetail.ColumnNames.unit.ToString(), 
                                            sales.Controls.gridOrderDetail.ColumnNames.price.ToString(),
                                            sales.Controls.gridOrderDetail.ColumnNames.amount.ToString()
                                           };

            this.myDetailGrid.SetColumnVisible(colList);
            this.myDetailGrid.myAutoFitColumn = sales.Controls.gridOrderDetail.ColumnNames.itemName.ToString();
            this.myDetailGrid.ReOrderColumn(colList);

            this.isAdminMode = this.isAdminMode;
            this.myHaveSecondGrid = false;
            return;
        }
        protected override common.myTypes.Permissions GetFormPermission()
        {
            return Settings.myPermission;
        }
        protected override bool BeforeSaveMasterRecord(DataRowView masterRow)
        {
            myInventoryData.Restart();
            if (!base.BeforeSaveMasterRecord(masterRow)) return false;
            bool retVal = true;

            common.myString errorMsg = new common.myString();
            data.salesDS.OrderDetailRow detailRow;
            data.salesDS.OrderRow orderRow = (data.salesDS.OrderRow)((DataRowView)orderSource.Current).Row;

            string orderId = orderRow.orderId;
            orderRow.ownerId = Settings.myPosConfig.CompanyId;
            orderRow.notes1 = "Bán hàng tại POS : " + posStationEd.Text.Trim() + " " + custNameEd.Text;
            try
            {
                progressBar.Visible = true;
                progressBar.Value = 0; progressBar.Maximum = myDetailGrid.Rows.Count;
                int idx;
                for (idx = 0; idx < myDetailGrid.Rows.Count; idx++)
                {
                    progressBar.Value++;
                    if (myDetailGrid.Rows[idx].DataBoundItem == null) continue;
                    detailRow = (data.salesDS.OrderDetailRow)((DataRowView)myDetailGrid.Rows[idx].DataBoundItem).Row;
                    if (detailRow[mySalesDS.OrderDetail.itemCodeColumn.ColumnName].ToString().Trim() == "")
                    {
                        this.myDetailGrid.Rows.RemoveAt(idx);
                        idx--;
                        continue;
                    }

                    errorMsg.Clear();
                    //Update the VoucherID and HouseCode
                    detailRow.itemCode = detailRow.itemCode.Trim();
                    detailRow.orderId = orderId;
                    
                    if (CheckValid_Detail(orderRow, myDetailGrid.Rows[idx], ref errorMsg) == false) retVal = false;
                    myDetailGrid.Rows[idx].ErrorText = errorMsg.ToString();
                }
                return retVal;
            }
            catch (Exception er)
            {
                this.ShowError(er);
                return false;
            }
            finally
            {
                progressBar.Visible = false;
            }
        }
        protected override bool AddNew(string editKey)
        {
            string saveCustCode = custCodeEd.lastValue;
            //Only
            mySalesDS.Order.Clear();
            data.salesDS.OrderRow orderRow = (data.salesDS.OrderRow)((DataRowView)myMasterSource.AddNew()).Row;
            DataAccess.DataLibs.InitData(orderRow);
            orderRow.OrderType = editKeyType;
            orderRow.OrderNo = editKey;
            orderRow.createById = CommonTypes.Settings.sysLoginInfo.UserId;
            this.custCodeEd.Text = saveCustCode;

            //Reset data to prevent date changed when the system run overnight to the next day
            dateEd.myDateTime = DateTime.Today;
            myInventoryData.Restart();
            myInventoryData.OnDate = dateEd.myDateTime;

            LockEditData(false);
            this.ShowMessage("", "Mới");
            return true;
        }
        protected override void SetFirstFocus()
        {
            this.myDetailGrid.Focus();
        }

        protected override string GetNewAutoEditKey()
        {
            data.salesDS.OrderDataTable tbl = new data.salesDS.OrderDataTable();
            string type = this.editKeyType;
            int expectedPrefixLen = CommonTypes.Settings.sysAutoVNumberSize;

            DateTime dt = dateEd.myDateTime;
            string tmp = dt.Year.ToString();
            tmp = tmp.Substring(tmp.Length - 2);
            string posStationCode = posStationEd.Text.Trim();
            string voucherPostfix = dt.Month.ToString().PadLeft(2, '0') + tmp;
            string findKey = voucherPostfix + posStationCode + "-" + type;

            //Detect possible oversized voucherNo to cut off storeHouse
            tmp = posStationCode;
            int overSize = posStationCode.Length - (tbl.OrderNoColumn.MaxLength - expectedPrefixLen - 6);
            if (overSize > 0) tmp = tmp.Substring(0, posStationCode.Length - overSize);
            voucherPostfix += "-" + tmp;
            while (true)
            {
                common.myTypes.AutoKeyInfo autoKeyInfo = application.SysLibs.GetAutoKey(findKey,false);
                application.SysLibs.CloseAutoKey(autoKeyInfo);
                if (expectedPrefixLen > 0) autoKeyInfo.EditKey = autoKeyInfo.EditKey.PadLeft(expectedPrefixLen, '0');
                autoKeyInfo.EditKey = autoKeyInfo.EditKey + "/" + voucherPostfix;
                tbl.Clear();
                DataAccess.DataLibs.LoadData(tbl, this.editKeyType, autoKeyInfo.EditKey);
                if (tbl.Count <= 0) return autoKeyInfo.EditKey;
                
            }
        }
        protected override void CloseAutoEditKey()
        {
            return;
        }

        protected override bool UpdateMasterTable(DataRow masterRow)
        {
            if (masterRow == null) DataAccess.DataLibs.UpdateData(mySalesDS.Order);
            else
            {
                data.salesDS.OrderRow orderRow = (data.salesDS.OrderRow)masterRow;
                orderRow.locationId = Settings.myPosConfig.PosStationId;
                DataAccess.DataLibs.UpdateData(orderRow);
            }
            return true;
        }
        protected override bool CancelAllChanges()
        {
            myMasterSource.CancelEdit();
            myDetailSource.CancelEdit();
            mySalesDS.RejectChanges();
            return true;
        }
        protected override bool SaveDetailData(string orderId)
        {
            if (!base.SaveDetailData(orderId)) return false;
            DataAccess.DataLibs.UpdateData(mySalesDS.OrderDetail);

            if (orderSource.Current == null) return false;
            data.salesDS.OrderRow orderRow = (data.salesDS.OrderRow)((DataRowView)orderSource.Current).Row;
            
            this.myInventoryData.SaveInventoryDetail(orderRow, mySalesDS.OrderDetail);
            this.myInventoryData.Refresh(this.myDetailGrid as sales.Controls.gridOrderDetail);
            
            return true;
        }
        protected override bool DataValid(bool showMsg)
        {
            ClearNotifyError();
            bool retVal = base.DataValid(showMsg);
            ShowCustomer();
            if (dateEd.myDateTime == common.Consts.constNullDate)
            {
                NotifyError(onDateLbl);
                retVal = false;
            }
            if (custCodeEd.Visible)
            {
                if (custCodeEd.Text.Trim() == "")
                {
                    NotifyError(custCodeLbl, "Chưa nhập Khách hàng.");
                    retVal = false;
                }
                else
                {
                    data.masterDS.CustomerRow custRow = DataAccess.DataCache.FindCUSTOMER(custCodeEd.Text);
                    if (custRow == null)
                    {
                        NotifyError(custCodeLbl,"Khách hàng không tồn tại.");
                        retVal = false;
                    }
                    else
                    {
                        if (custRow.status != (int)common.CommonStatus.Enabled)
                        {
                            NotifyError(custCodeLbl,"Khách hàng bị khoá.");
                            retVal = false;
                        }
                    }
                }
            }

            if (detailSource.Count<=0)
            {
                common.SysLibs.ShowMessage("Ít nhất phải có 01 mặt hàng");
                retVal = false;
            }
            return retVal;
        }
        protected override bool FillMasterTable(string editKeyId)
        {
            mySalesDS.Order.Clear();
            DataAccess.DataLibs.LoadData(mySalesDS.Order, editKeyId);
            ShowCustomer();
            return true;
        }
        protected override DataTable FillMasterNavigatorTable(string editType)
        {
            mySalesDS.navOrder.Clear();
            DataAccess.DataLibs.LoadData(mySalesDS.navOrder, editKeyType);
            return mySalesDS.navOrder;
        }
        protected override bool FillDetailTable(string editKeyId)
        {
            mySalesDS.OrderDetail.Clear();
            DataAccess.DataLibs.LoadDataMain(mySalesDS.OrderDetail, editKeyId);
            this.myDetailGrid.Refresh();
            return true;
        }

        protected override void AfterDataSaved(DataRowView dr)
        {
            base.AfterDataSaved(dr);
            if (this.isAdminMode == false)
            {
                LockEditData(true);
                Print(false);
            }
        }
        protected override bool RemoveCurrent()
        {
            data.salesDS.OrderRow orderRow = (data.salesDS.OrderRow)((DataRowView)myMasterSource.Current).Row;
            string voucherId = (orderRow.IsrefVoucherIdNull() ? null : orderRow.refVoucherId); 
            if (base.RemoveCurrent() == false) return false;

            if (common.StringLibs.IsNullOrEmpty(voucherId)==false)
                DataAccess.DataLibs.DeleteVoucher(voucherId);
            return true;
        }
        
        protected override void ShowSubTotal()
        {
            decimal subTotal = 0;
            data.salesDS.OrderDetailRow detailRow;
            for (int idx = 0; idx < myDetailGrid.Rows.Count; idx++)
            {
                if (myDetailGrid.Rows[idx].DataBoundItem == null) continue;
                detailRow = (data.salesDS.OrderDetailRow)((DataRowView)myDetailGrid.Rows[idx].DataBoundItem).Row;
                if (detailRow.deleted) continue;
                subTotal += detailRow.amount;
            }
            this.subTotalEd.Value = subTotal;
            this.ShowReccount(mySalesDS.OrderDetail.Count);
        }

        report.reportDS.retailSaleOrderDataTable myReportTbl = new report.reportDS.retailSaleOrderDataTable();
        protected void GetReportData(report.reportDS.retailSaleOrderDataTable reportTbl)
        {
            reportTbl.Clear();
            data.masterDS.ItemRow itemRow;
            report.reportDS.retailSaleOrderRow reportRow;
            for (int idx1 = 0; idx1 < mySalesDS.OrderDetail.Count; idx1++)
            {
                if (mySalesDS.OrderDetail[idx1].RowState == DataRowState.Deleted) continue;
                reportRow = myReportTbl.NewretailSaleOrderRow();
                reportRow.itemCode = mySalesDS.OrderDetail[idx1].itemCode;
                reportRow.qty = mySalesDS.OrderDetail[idx1].qty;
                reportRow.amt = mySalesDS.OrderDetail[idx1].amount;
                itemRow = DataAccess.DataCache.FindITEM(reportRow.itemCode);
                if (itemRow!=null) reportRow.itemName = itemRow.name;
                myReportTbl.AddretailSaleOrderRow(reportRow);
            }
        }

        CrystalDecisions.CrystalReports.Engine.ReportClass myReport = null;
        public override void Print(bool fPreview)
        {
            myReportTbl.Clear();
            GetReportData(myReportTbl);
            if (myReport == null) myReport = new report.saleOrderRetailReport();
            myReport.SetDataSource(myReportTbl.DefaultView);
            //Report parametters
            string[] reportData = new string[]{"HOÁ ĐƠN BÁN LẺ",
                                               "Quầy : " + this.posStationEd.Text,
                                               this.dateEd.myDateTime.ToShortDateString(),
                                               CommonTypes.Settings.sysLoginInfo.FullName,
                                               this.editKeyEd.Text,
                                               this.custCodeEd.Text.Trim() + " - " +this.custNameEd.Text.Trim(),
                                               ""
                                            };
            string[] reportTitle = application.ReportLibs.CompanyHeader(null);

            this.SetReport(myReport);
            this.SetReport(reportData, "reportData");
            this.SetReport(reportTitle,"reportTitle");

            this.myReportViewer.myShowPrintDialog = false; // this.isAdminMode;
            this.ShowReport(fPreview);
            return;
        }

        protected override void ShowCreatorInfo()
        {
            if (orderSource.Current == null) return;
            data.salesDS.OrderRow dataRow = (data.salesDS.OrderRow)((DataRowView)orderSource.Current).Row;
            data.masterDS.workerRow workerRow;
            string info = "";
            workerRow = DataAccess.DataLibs.GetWorkerById(dataRow.createById);
            if (workerRow != null)
                info += "Tạo lập : " + workerRow.fname.Trim() + " " + workerRow.lname.Trim() + " [" + workerRow.login.Trim() + "]";

            if (dataRow.IseditByIdNull() == false)
            {
                workerRow = DataAccess.DataLibs.GetWorkerById(dataRow.editById);
                if (workerRow != null)
                    info += common.Consts.constCRLF + "Thay đổi : " + workerRow.fname.Trim() + " " + workerRow.lname.Trim() + " [" + workerRow.login.Trim() + "]";
            }
            if (common.StringLibs.IsNullOrEmpty(info) == false) common.SysLibs.ShowMessage(info);
        }

        protected override bool DataChangable()
        {
            DataRowView drOrder = (DataRowView)orderSource.Current;
            if (drOrder == null) return false;
            if (drOrder.IsNew==false)
            {
                drOrder[mySalesDS.Order.editByIdColumn.ColumnName] = CommonTypes.Settings.sysLoginInfo.UserId;
            }
            return true;
        }
        #endregion

        protected bool CheckValid_Detail(data.salesDS.OrderRow orderRow, DataGridViewRow viewRow, ref common.myString errorMsg)
        {
            data.salesDS.OrderDetailRow detailRow = (data.salesDS.OrderDetailRow)((DataRowView)viewRow.DataBoundItem).Row;
            if (detailRow[mySalesDS.OrderDetail.itemCodeColumn.ColumnName].ToString().Trim() == "") return true;

            bool retVal = true;
            if (detailRow.qty<=0)
            {
                errorMsg.Add("Chưa nhập số lượng");
                retVal = false;
            }
            if (detailRow.price <= 0)
            {
                errorMsg.Add("Chưa có giá");
                retVal = false;
            }

            data.masterDS.ItemRow itemRow = DataAccess.DataCache.FindITEM(detailRow.itemCode);
            if (itemRow == null)
            {
                errorMsg.Add(application.AppLibs.GetText(application.AppLibs.DataErrors.ItemCodeInvalid));
                retVal = false;
            }
            else
            {
                if (itemRow.status == (byte)common.CommonStatus.Disabled)
                {
                    errorMsg.Add(application.AppLibs.GetText(application.AppLibs.DataErrors.ItemCodeLocked));
                    retVal = false;
                }
                if (sysCheckInventoryQty)
                {
                    data.tmpDS.inventoryRow inventoryRow = myInventoryData.UpdateInventory(itemRow.itemCode, detailRow.qty);
                    if (inventoryRow != null)
                    {
                        viewRow.Cells[inventory.Controls.gridInventoryDetail.ColumnNames.whQty.ToString()].Value = inventoryRow.eopQty;
                        if (inventoryRow.eopQty < 0)
                        {
                            errorMsg.Add("Tồn kho âm");
                            retVal = false;
                        }
                    }
                    else
                    {
                        viewRow.Cells[inventory.Controls.gridInventoryDetail.ColumnNames.whQty.ToString()].Value = 0;
                        errorMsg.Add("Không có hàng.");
                        retVal = false;
                    }
                }
            }
            return retVal;
        }
        protected void AddNewRow()
        {
            this.custCodeEd.Text = ""; 
            this.custCodeEd.EndChanged();
            this.custNameEd.Text = "";
            this.custAddressEd.Text = "";
            string editKey = common.Settings.sysNewEditKeyAutoMarker;
            AddNew(editKey);
            this.editKeyEd.Text = editKey;
            FillDetailTable(editKeyEd.Text);
            LockEdit();
            this.custCodeEd.Focus();
        }

        protected void Init()
        {
            this.AutoEditKeyMode = true;
            //editKeyEd.Visible = true;
            //companyIdEd.Visible = true;
            //orderIdEd.Visible = true;
            this.myFormCode = this.Name;
            this.editKeyType = CommonTypes.SaleConsts.constOrderRetail;

            this.myDetailGrid.RowTemplate.Height = 30;
            this.myDetailGrid.DefaultCellStyle.Font = new Font(this.Font.FontFamily, 12);
            
        }
        protected bool LoadConfig()
        {
            if (Settings.myPosConfig == null) return false;
            this.companyNameEd.Text = Settings.myPosConfig.CompanyName;
            this.posStationEd.Text = Settings.myPosConfig.PosStationCode;
            return true;
        }

        protected decimal GetSalePrice(string itemCode)
        {
            data.salesDS.ItemPriceRow itemPriceRow = sales.AppLibs.GetItemPriceData(CommonTypes.InventoryConsts.constStatementItemPriceSaleInternal, this.myCurrency, dateEd.myDateTime, itemCode);
            if (itemPriceRow == null) return 0;
            return itemPriceRow.price1;
        }
        protected void ShowCustomer()
        {
            string code = custCodeEd.Text.Trim();
            if (code == "")
            {
                this.custNameEd.Text = ""; this.custAddressEd.Text = "";
                return;
            }
            data.masterDS.CustomerRow row = DataAccess.DataCache.FindCUSTOMER(code);
            if (row == null)
            {
                this.custNameEd.Text = ""; this.custAddressEd.Text = "";
                return;
            }
            this.custNameEd.Text = row.name1;
            this.custAddressEd.Text = row.address1;
        }
        protected void CalculateAmount()
        {
            if (myDetailGrid.CurrentRow == null) return;
            if (!myDetailGrid.Columns[sales.Controls.gridOrderDetail.ColumnNames.qty.ToString()].Visible || !myDetailGrid.Columns[sales.Controls.gridOrderDetail.ColumnNames.price.ToString()].Visible) return;

            double qty = 0, price = 0;
            common.StringLibs.Str2Double(this.myDetailGrid.CurrentRow.Cells[sales.Controls.gridOrderDetail.ColumnNames.qty.ToString()].Value.ToString(), out qty);
            common.StringLibs.Str2Double(this.myDetailGrid.CurrentRow.Cells[sales.Controls.gridOrderDetail.ColumnNames.price.ToString()].Value.ToString(), out price);
            this.myDetailGrid.CurrentRow.Cells[sales.Controls.gridOrderDetail.ColumnNames.amount.ToString()].Value = qty * price;
        }
        

        #region event handler

        private void gridValueChanged(object sender, common.controls.GridEventArgs e)
        {
            if (myDetailGrid.CurrentCell == null) return;
            string columName = myDetailGrid.Columns[e.ColumnIndex].Name;
            if (columName == sales.Controls.gridOrderDetail.ColumnNames.itemCode.ToString())
            {
                string itemCode = myDetailGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
                if (common.StringLibs.IsNullOrEmpty(itemCode) == false)
                {
                    bool HaveMarker = common.SysLibs.HaveFindMarker(ref itemCode);
                    if (HaveMarker == false)
                    {
                        string code = application.AppLibs.GetItemCodeFromCodeId(itemCode);
                        if (code != null)
                        {
                            itemCode = code;
                            myDetailGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = itemCode;
                        }
                    }
                }
                data.masterDS.ItemRow itemRow = DataAccess.DataCache.FindITEM(itemCode);
                if (itemRow == null)
                {
                    application.dataFind.myItemFind.Find(itemCode);
                    if (application.dataFind.myItemFind.selectedDataRow != null)
                        itemRow = DataAccess.DataCache.FindITEM(application.dataFind.myItemFind.selectedDataRow.itemCode);
                }
                if (itemRow != null)
                {
                    myDetailGrid.CurrentRow.Cells[columName].Value = itemRow.itemCode;
                    //Item price
                    decimal salePrice = 0;
                    if (myDetailGrid.Columns[sales.Controls.gridOrderDetail.ColumnNames.price.ToString()].Visible)
                    {
                        salePrice = GetSalePrice(itemRow.itemCode);
                        myDetailGrid.CurrentRow.Cells[sales.Controls.gridOrderDetail.ColumnNames.price.ToString()].Value = salePrice;
                        CalculateAmount();
                    }
                    data.tmpDS.inventoryRow inventoryRow = myInventoryData.GetInventory(itemRow.itemCode);
                    if (inventoryRow != null)
                         myDetailGrid.CurrentRow.Cells[sales.Controls.gridOrderDetail.ColumnNames.whQty.ToString()].Value = inventoryRow.eopQty;
                    else myDetailGrid.CurrentRow.Cells[sales.Controls.gridOrderDetail.ColumnNames.whQty.ToString()].Value = 0;
                }
                else
                {
                    myDetailGrid.CurrentRow.Cells[columName].Value = null;
                }
                if (myDetailGrid.Rows[e.RowIndex].Cells[sales.Controls.gridOrderDetail.ColumnNames.qty.ToString()].Value == null ||
                    (decimal)myDetailGrid.Rows[e.RowIndex].Cells[sales.Controls.gridOrderDetail.ColumnNames.qty.ToString()].Value == 0)
                {
                    myDetailGrid.Rows[e.RowIndex].Cells[sales.Controls.gridOrderDetail.ColumnNames.qty.ToString()].Value = 1;
                    CalculateAmount();
                }
            }
            if (columName == sales.Controls.gridOrderDetail.ColumnNames.qty.ToString()) { CalculateAmount(); }
            if (columName == sales.Controls.gridOrderDetail.ColumnNames.price.ToString()) { CalculateAmount(); }
            myDetailSource.ResetCurrentItem();
            this.myDetailGrid.Focus();
            ShowSubTotal();
        }
        private void finishBtn_Click(object sender, EventArgs e)
        {
            try
            {
                CancelAllChanges();
                AddNewRow();
            }
            catch (Exception er)
            {
                ShowError(er);
            }
        }
        private void custCodeEd_Validated(object sender, EventArgs e)
        {
            try
            {
                ShowCustomer();
            }
            catch (Exception er)
            {
                ShowError(er);
            }
        }
        #endregion
    }
}
